<template>
  <div ref="chartContainer" class="horizontal-bar-chart"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue";
import * as d3 from "d3";

// 类型定义
interface BarData {
  name: string;          // 左侧标签
  value: number;         // 进度值
  maxValue: number;      // 最大值（用于计算百分比）
  rightLabel?: string;   // 右侧标签（可选）
  color?: string;        // 进度条颜色（可选）
}

// 组件引用
const chartContainer = ref<HTMLElement>();

// 示例数据
const chartData: BarData[] = [
  { name: "项目A", value: 65, maxValue: 100, rightLabel: "65%", color: "#4dabf7" },
  { name: "项目B", value: 40, maxValue: 100, rightLabel: "40%", color: "#ffa502" },
  { name: "项目C", value: 85, maxValue: 100, rightLabel: "85%", color: "#2ed573" },
  { name: "项目D", value: 30, maxValue: 100, rightLabel: "30%", color: "#ff6b81" },
  { name: "项目E", value: 95, maxValue: 100, rightLabel: "95%", color: "#5f27cd" },
];

// 图表配置
const config = {
  height: 210,                  // 图表高度
  barHeight: 14,                // 每个条目的高度
  barPadding: 3,                // 条目间距
  leftLabelWidth: 80,           // 左侧标签宽度
  rightLabelWidth: 50,          // 右侧标签宽度
  barRadius: 8,                 // 进度条圆角
  defaultColor: "#3498db",      // 默认进度条颜色
  bgColor: "#ecf0f1",           // 背景条颜色
  textColor: "#fff",         // 文本颜色
  fontSize: "12px"              // 字体大小
};

let resizeObserver: ResizeObserver;

// 生命周期钩子
onMounted(() => {
  renderChart();
  initResizeObserver();
});

onBeforeUnmount(() => {
  resizeObserver?.disconnect();
});

// 响应式调整
const initResizeObserver = () => {
  if (!chartContainer.value) return;

  resizeObserver = new ResizeObserver(() => {
    renderChart();
  });
  resizeObserver.observe(chartContainer.value);
};

// 主渲染函数
const renderChart = () => {
  if (!chartContainer.value) return;

  // 清除旧图表
  d3.select(chartContainer.value).selectAll("*").remove();

  // 计算宽度
  const containerWidth = chartContainer.value.clientWidth;
  const chartWidth = containerWidth - config.leftLabelWidth - config.rightLabelWidth - 20;

  // 创建SVG容器
  const svg = d3.select(chartContainer.value)
    .append("svg")
    .attr("width", "100%")
    .attr("height", config.height)
    .attr("viewBox", `0 0 ${containerWidth} ${config.height}`)
    .style("background", "transparent");

  // 创建图表组
  const chart = svg.append("g")
    .attr("transform", `translate(10, 20)`);

  // 创建比例尺
  const xScale = d3.scaleLinear()
    .domain([0, d3.max(chartData, d => d.maxValue) || 100])
    .range([0, chartWidth])
    .nice();

  // 创建Y轴位置比例
  const yScale = d3.scaleBand()
    .domain(chartData.map((_d, i) => i.toString()))
    .range([0, config.height - 40])
    .padding(0.2);

  // 绘制背景条
  chart.selectAll(".bar-bg")
    .data(chartData)
    .enter()
    .append("rect")
    .attr("class", "bar-bg")
    .attr("x", config.leftLabelWidth)
    .attr("y", (_d, i) => yScale(i.toString())!)
    .attr("width", chartWidth)
    .attr("height", config.barHeight)
    .attr("rx", config.barRadius)
    .attr("ry", config.barRadius)
    .attr("fill", config.bgColor).attr("stroke", "#08aaf5")  // 添加边框颜色
  .attr("stroke-width", 3);  // 添加边框宽度;

  // 绘制进度条
  chart.selectAll(".bar-progress")
    .data(chartData)
    .enter()
    .append("rect")
    .attr("class", "bar-progress")
    .attr("x", config.leftLabelWidth)
    .attr("y", (_d, i) => yScale(i.toString())!)
    .attr("width", d => xScale(d.value))
    .attr("height", config.barHeight)
    .attr("rx", config.barRadius)
    .attr("ry", config.barRadius)
    .attr("fill", d => d.color || config.defaultColor)
    .transition()
    .duration(800)
    .attr("width", d => xScale(d.value));

  // 添加左侧标签
  chart.selectAll(".left-label")
    .data(chartData)
    .enter()
    .append("text")
    .attr("class", "left-label")
    .attr("x",  config.leftLabelWidth - 5)
    .attr("y", (_d, i) => yScale(i.toString())! + config.barHeight / 2)
    .attr("dy", "0.35em")
    .attr("text-anchor", "end")  // 设置为右对齐
    .attr("fill", config.textColor)
    .style("font-size", config.fontSize)
    .text(d => d.name);

  // 添加右侧标签
  chart.selectAll(".right-label")
    .data(chartData)
    .enter()
    .append("text")
    .attr("class", "right-label")
    .attr("x", config.leftLabelWidth + chartWidth + 5)
    .attr("y", (_d, i) => yScale(i.toString())! + config.barHeight / 2)
    .attr("dy", "0.35em")
    .attr("text-anchor", "start")
    .attr("fill", config.textColor)
    .style("font-size", config.fontSize)
    .text(d => d.rightLabel || `${Math.round((d.value / d.maxValue) * 100)}%`);

  // 可选：在进度条上添加值标签
  chart.selectAll(".value-label")
    .data(chartData)
    .enter()
    .append("text")
    .attr("class", "value-label")
    .attr("x", d => config.leftLabelWidth + xScale(d.value) - 5)
    .attr("y", (_d, i) => yScale(i.toString())! + config.barHeight / 2)
    .attr("dy", "0.35em")
    .attr("text-anchor", "end")
    .attr("fill", "#fff")
    .style("font-size", config.fontSize)
    .style("font-weight", "bold")
    .text(d => d.value+"%");
};
</script>

<style scoped>
.horizontal-bar-chart {
  width: 100%;
  height: 100%;
  font-family: Arial, sans-serif;
}

.bar-progress {
  transition: width 0.3s ease;
}
</style>